﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Routing;
using Nb.Common.Ioc;
using Nb.Common.Themes.Providers;

namespace Nb.Common.Themes
{
    /// <summary>
    /// 可以多个Provider中读取，按优先级提供，比如
    /// query, cookie, config, services...
    /// </summary>
    public class ThemeManager
    {
        public static string GetTheme(RequestContext requestContext)
        {
            //read cache in requestContext
            string currentTheme = ThemeViewBag.Current.Theme;
            if (currentTheme != null)
            {
                return currentTheme;
            }

            var themeProviders = new List<IThemeProvider>();
            themeProviders.AddRange(_defaultThemeProviders);

            if (_needSearchAllProviders)
            {
                var providers = CoreServiceProvider.Current.GetAllInstances<IThemeProvider>()
                    .Where(p =>
                        p.GetType() != typeof(QueryStringValueProvider)
                        && p.GetType() != typeof(ConfigThemeProvider))
                    .ToList();

                //Count > 0，意味着定义了其他的Provider
                //否则，下次没有机会在执行此代码块
                _needSearchAllProviders = providers.Count > 0;
            }

            //值越大，越靠前
            var theme = FindTheme(themeProviders, requestContext);
            ThemeViewBag.Current.Theme = theme;
            return theme;
        }

        #region helpers

        private static bool _needSearchAllProviders = true;
        private static IList<IThemeProvider> _defaultThemeProviders = new List<IThemeProvider>
        {
            new QueryThemeProvider(),
            new ConfigThemeProvider()
        };
        private static string FindTheme(IEnumerable<IThemeProvider> themeProviders, RequestContext requestContext)
        {
            //值越大，越靠前
            var themes = themeProviders.OrderByDescending(x => x.Priority)
                .Select(x => x.GetTheme(requestContext))
                .OrderByDescending(t => t.Priority)
                .ThenBy(x => x.Provider);

            string result = null;
            foreach (var theme in themes)
            {
                //优先度越高，越先查找
                if (!string.IsNullOrWhiteSpace(theme.Name))
                {
                    result = theme.Name;
                    break;
                }
            }

            return result;
        }

        #endregion
    }
}
